home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / board / UChessSrc.lha / eval.c < prev    next >
C/C++ Source or Header  |  1994-08-05  |  55KB  |  2,071 lines

  1. #define WAY4PL64 1 // for K1PK code
  2. //#define PRE4PL67 1 // go back to 4pl63/64 stuff
  3. /*
  4.  * eval.c - C source for GNU CHESS
  5.  *
  6.  * Copyright (c) 1988,1989,1990 John Stanback
  7.  * Copyright (c) 1992 Free Software Foundation
  8.  *
  9.  * This file is part of GNU CHESS.
  10.  *
  11.  * GNU Chess is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2, or (at your option)
  14.  * any later version.
  15.  *
  16.  * GNU Chess is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with GNU Chess; see the file COPYING.  If not, write to
  23.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  */
  25. #include "gnuchess.h"
  26. #include "ataks.h"
  27. int __aligned EADD = 0;
  28. int __aligned EGET = 0;
  29. int __aligned PUTVAR = false;
  30. #ifdef CACHE
  31. struct etable __far __aligned etab[2][ETABLE];
  32. #endif
  33.  
  34. int ScoreKBNK (short winner, short king1, short king2);
  35. int ScoreKPK (short side,
  36.       short winner,
  37.       short loser,
  38.       short king1,
  39.       register short king2,
  40.       register short sq);
  41.  
  42.  
  43. extern short __aligned PCRASH,PCENTER;
  44. short __aligned QueenCheck[MAXDEPTH]; /* tom@izf.tno.nl */
  45. int __aligned myneweval=1;
  46. short int __aligned sscore[2];
  47. /* Backward pawn bonus indexed by # of attackers on the square */
  48. static const short __aligned BACKWARD[16] =
  49. {-6, -10, -15, -21, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28};
  50.  
  51. /* Bishop mobility bonus indexed by # reachable squares */
  52. static const short __aligned BMBLTY[14] =
  53. {-2, 0, 2, 4, 6, 8, 10, 12, 13, 14, 15, 16, 16, 16};
  54.  
  55. /* Rook mobility bonus indexed by # reachable squares */
  56. static const short __aligned RMBLTY[15] =
  57. {0, 2, 4, 6, 8, 10, 11, 12, 13, 14, 14, 14, 14, 14, 14};
  58.  
  59. /* Positional values for a dying king */
  60. static const short __aligned DyingKing[64] =
  61. {0, 8, 16, 24, 24, 16, 8, 0,
  62.  8, 32, 40, 48, 48, 40, 32, 8,
  63.  16, 40, 56, 64, 64, 56, 40, 16,
  64.  24, 48, 64, 72, 72, 64, 48, 24,
  65.  24, 48, 64, 72, 72, 64, 48, 24,
  66.  16, 40, 56, 64, 64, 56, 40, 16,
  67.  8, 32, 40, 48, 48, 40, 32, 8,
  68.  0, 8, 16, 24, 24, 16, 8, 0};
  69.  
  70. /* Isoloted pawn penalty by rank */
  71. static const short __aligned ISOLANI[8] =
  72. {-12, -16, -20, -24, -24, -20, -16, -12};
  73.  
  74. /* table for King Bishop Knight endings */
  75. static const short __aligned KBNK[64] =
  76. #ifdef PRE4PL67KBNK
  77. {99, 90, 80, 70, 60, 50, 40, 40,
  78.  90, 80, 60, 50, 40, 30, 20, 40,
  79.  80, 60, 40, 30, 20, 10, 30, 50,
  80.  70, 50, 30, 10, 0, 20, 40, 60,
  81.  60, 40, 20, 0, 10, 30, 50, 70,
  82.  50, 30, 10, 20, 30, 40, 60, 80,
  83.  40, 20, 30, 40, 50, 60, 80, 90,
  84.  40, 40, 50, 60, 70, 80, 90, 99};
  85. #else
  86. {620, 560, 500, 440, 380, 320, 260, 240,
  87.  560, 520, 460, 400, 340, 280, 230, 260,
  88.  500, 460, 320, 280, 260, 220, 280, 320,
  89.  440, 400, 280, 200, 200, 260, 340, 380,
  90.  380, 340, 260, 200, 200, 280, 400, 440,
  91.  320, 280, 220, 260, 280, 320, 460, 500,
  92.  260, 230, 280, 340, 400, 460, 520, 560,
  93.  240, 260, 320, 380, 440, 500, 560, 620};
  94. #endif
  95.  
  96. /* penalty for threats to king, indexed by number of such threats */
  97. static const short __aligned KTHRT[36] =
  98. {0, -8, -20, -36, -52, -68, -80, -80, -80, -80, -80, -80,
  99.  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
  100.  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80};
  101.  
  102. /* King positional bonus inopening stage */
  103. static const short __aligned KingOpening[64] =
  104. {0, 0, -4, -10, -10, -4, 0, 0,
  105.  -4, -4, -8, -12, -12, -8, -4, -4,
  106.  -12, -16, -20, -20, -20, -20, -16, -12,
  107.  -16, -20, -24, -24, -24, -24, -20, -16,
  108.  -16, -20, -24, -24, -24, -24, -20, -16,
  109.  -12, -16, -20, -20, -20, -20, -16, -12,
  110.  -4, -4, -8, -12, -12, -8, -4, -4,
  111.  0, 0, -4, -10, -10, -4, 0, 0};
  112.  
  113. /* King positional bonus in end stage */
  114. static const short __aligned KingEnding[64] =
  115. {0, 6, 12, 18, 18, 12, 6, 0,
  116.  6, 12, 18, 24, 24, 18, 12, 6,
  117.  12, 18, 24, 30, 30, 24, 18, 12,
  118.  18, 24, 30, 36, 36, 30, 24, 18,
  119.  18, 24, 30, 36, 36, 30, 24, 18,
  120.  12, 18, 24, 30, 30, 24, 18, 12,
  121.  6, 12, 18, 24, 24, 18, 12, 6,
  122.  0, 6, 12, 18, 18, 12, 6, 0};
  123.  
  124. /* Passed pawn positional bonus */
  125. static const short __aligned PassedPawn0[8] =
  126. {0, 60, 80, 120, 200, 360, 600, 800};
  127. static const short __aligned PassedPawn1[8] =
  128. {0, 30, 40, 60, 100, 180, 300, 800};
  129. static const short __aligned PassedPawn2[8] =
  130. {0, 15, 25, 35, 50, 90, 140, 800};
  131. static const short __aligned PassedPawn3[8] =
  132. {0, 5, 10, 15, 20, 30, 140, 800};
  133.  
  134. /* Knight positional bonus */
  135. static const short __aligned pknight[64] =
  136. {0, 4, 8, 10, 10, 8, 4, 0,
  137.  4, 8, 16, 20, 20, 16, 8, 4,
  138.  8, 16, 24, 28, 28, 24, 16, 8,
  139.  10, 20, 28, 32, 32, 28, 20, 10,
  140.  10, 20, 28, 32, 32, 28, 20, 10,
  141.  8, 16, 24, 28, 28, 24, 16, 8,
  142.  4, 8, 16, 20, 20, 16, 8, 4,
  143.  0, 4, 8, 10, 10, 8, 4, 0};
  144.  
  145. /* Bishop positional bonus */
  146. static const short __aligned pbishop[64] =
  147. {14, 14, 14, 14, 14, 14, 14, 14,
  148.  14, 22, 18, 18, 18, 18, 22, 14,
  149.  14, 18, 22, 22, 22, 22, 18, 14,
  150.  14, 18, 22, 22, 22, 22, 18, 14,
  151.  14, 18, 22, 22, 22, 22, 18, 14,
  152.  14, 18, 22, 22, 22, 22, 18, 14,
  153.  14, 22, 18, 18, 18, 18, 22, 14,
  154.  14, 14, 14, 14, 14, 14, 14, 14};
  155.  
  156. /* Pawn positional bonus */
  157. static const short __aligned PawnAdvance[64] =
  158. {0, 0, 0, 0, 0, 0, 0, 0,
  159.  4, 4, 4, 0, 0, 4, 4, 4,
  160.  6, 8, 2, 10, 10, 2, 8, 6,
  161.  6, 8, 12, 16, 16, 12, 8, 6,
  162.  8, 12, 16, 24, 24, 16, 12, 8,
  163.  12, 16, 24, 32, 32, 24, 16, 12,
  164.  12, 16, 24, 32, 32, 24, 16, 12,
  165.  0, 0, 0, 0, 0, 0, 0, 0};
  166.  
  167.  
  168. #define AHOPEN (-250)
  169.  
  170. short __aligned Mwpawn[64];
  171. short __aligned Mbpawn[64];
  172. short __aligned Mknight[2][64];
  173. short __aligned Mbishop[2][64];
  174. static short __aligned Mking[2][64];
  175. static short __aligned Kfield[2][64];
  176. static short __aligned c1, c2, *atk1, *atk2, *PC1, *PC2;
  177. static short __aligned atak[2][64];
  178. short __aligned emtl[2];
  179. static short __aligned PawnBonus, BishopBonus, RookBonus;
  180. static short __aligned KNIGHTPOST, KNIGHTSTRONG, BISHOPSTRONG, KATAK;
  181. static short __aligned PEDRNK2B, PWEAKH, PADVNCM, PADVNCI, PAWNSHIELD, PDOUBLED, PBLOK;
  182. static short __aligned RHOPN, RHOPNX, KHOPN, KHOPNX, KSFTY;
  183. static short __aligned ATAKD, HUNGP, HUNGX, KCASTLD, KMOVD, XRAY, PINVAL;
  184. short __aligned pscore[2];
  185. short __aligned tmtl;
  186.  
  187. #ifdef CACHE
  188. inline void
  189. PutInEETable (ARGSZ int side,int score)
  190.  
  191. /*
  192.  * Store the current eval position in the transposition table.
  193.  */
  194.  
  195. {
  196.     register struct etable *ptbl;
  197.     ptbl = &etab[side][hashkey % (ETABLE)];
  198. //    if (ptbl->ehashbd == hashbd) return;
  199.     ptbl->ehashbd = hashbd;
  200.     ptbl->escore[white] = pscore[white];
  201.     ptbl->escore[black] = pscore[black];
  202.     ptbl->hung[white] = hung[white];
  203.     ptbl->hung[black] = hung[black];
  204.     ptbl->score = score;
  205. #ifndef AMIGA
  206.     memcpy ( &(ptbl->sscore), svalue, sizeof (svalue));
  207. #else
  208.     MoveMem128(svalue,&(ptbl->sscore));
  209.    /* MoveMem(svalue,&(ptbl->sscore),sizeof (svalue));*/
  210. #endif
  211. /*    bcopy (&(ptbl->sscore), svalue, sizeof (svalue)); */
  212. #if !defined CHESSTOOL && !defined XBOARD
  213.     EADD++;
  214. #endif
  215.     return;
  216. }
  217.  
  218. inline int
  219. CheckEETable (ARGSZ int side)
  220.  
  221. /* Get an evaluation from the transposition table */
  222. {
  223.     register struct etable *ptbl;
  224.     ptbl = &etab[side][hashkey % (ETABLE)];
  225.     if (hashbd == ptbl->ehashbd) return true;
  226.     return false;
  227. }
  228.  
  229. inline int
  230. ProbeEETable (short int side, short int *score)
  231.  
  232. /* Get an evaluation from the transposition table */
  233. {
  234.     register struct etable *ptbl;
  235.     ptbl = &etab[side][hashkey % (ETABLE)];
  236.     if (hashbd == ptbl->ehashbd)
  237.       {
  238.       pscore[white] = ptbl->escore[white];
  239.       pscore[black] = ptbl->escore[black];
  240. #ifndef AMIGA
  241.       memcpy (svalue, &(ptbl->sscore), sizeof (svalue));
  242. #else
  243.       MoveMem128(&(ptbl->sscore),svalue);
  244.      /* MoveMem (&(ptbl->sscore),svalue, sizeof (svalue));*/
  245. #endif
  246.       *score = ptbl->score;
  247.           hung[white] = ptbl->hung[white];
  248.           hung[black] = ptbl->hung[black];
  249. #if !defined CHESSTOOL && !defined XBOARD
  250.       EGET++;
  251. #endif
  252.       return true;
  253.       }
  254.     return false;
  255.  
  256. }
  257.  
  258. #endif
  259.  
  260.  
  261.  
  262. short dist_ (short, short, short, short);
  263. short kpkwv_ (short, short, short, short, short, short);
  264.  
  265. #ifndef PRE4PL67
  266.  
  267. short 
  268. kpkwv_ (short pf, short pr, short wf, short wr, short bf, short br)
  269. {
  270.  
  271.   /*
  272.    *  Don Beal's routine, which was originally in Fortran.  See AICC 2
  273.    */
  274.  
  275.   static short wbdd, mbpf, nbpf, blpu;
  276.   short dist_ (short, short, short, short);
  277.   static short brpu, mwpf, wlpu, wrpu, blpuu, brpuu, wlpuu, wrpuu, md,
  278.     bq, blpuuu, brpuuu, bsd, tbf, sgf, bpp, sdr, sgr, wsd, wsg, ppr, wpp;
  279.  
  280.   ppr = ((pr == 2)?3:pr); // was ?3:0
  281.   if (pf == 1)
  282.   { if (bf == 3)
  283.     { if (pr == 7 && wf == 1 && wr == 8 && br > 6) return(0);
  284.       if (pr == 6 && wf < 4 && wr == 6 && br == 8) return(1);
  285.     }
  286.  
  287.     if (bf == 1 && br > pr) return(0);
  288.     if (pr == 7 && bf > 2) return(1);
  289.     if (bf <= 3 && br - ppr > 1) return(0);
  290.     if (wf == 1 && bf == 3 && wr - pr == 1 && br - pr == 1) return(0);
  291.   }
  292.   bq = dist_ (bf, br, pf, 8);
  293.   if (bq > 8 - ppr) return(1);
  294.   mbpf = bf - pf;
  295.   if (mbpf < 0) mbpf = -mbpf;
  296.   bpp = dist_ (bf, br, pf, ppr);
  297.   wpp = dist_ (wf, wr, pf, ppr);
  298.   if (bpp - wpp < -1 && br - pr != mbpf) return(0);
  299.   if (pf == 1 && pr <= 3 && wf <= 2 && wr == 8 && bf == 4 && br >= 7) return(1);
  300.   if (!(pf != 2 || pr != 6 || bf != 1 || br != 8))
  301.   { if (wf <= 3 && wr == 6) return(0);
  302.     if (wf == 4 && wr == 8) return(0);
  303.   }
  304.   if (pr == 7)
  305.   { if (wr < 8 && wpp == 2 && bq == 0) return(1);
  306.     if (wr == 6 && wf == pf && bq == 0) return(1);
  307.     if (wr >= 6 && wpp <= 2 && bq != 0) return(1);
  308.   }
  309.   blpuu = dist_ (bf, br, pf - 1, pr + 2);
  310.   wbdd = dist_ (wf, wr, bf, br - 2);
  311.   brpuu = dist_ (bf, br, pf + 1, pr + 2);
  312.   if (pr == 6)
  313.   { if (dist_ (bf, br, pf + 1, pr) > 1 &&
  314.         brpuu > dist_ (wf, wr, pf + 1, pr)) return(1);
  315.     if (pf != 1)
  316.     { if (blpuu > dist_ (wf, wr, pf - 1, pr)) return(1);
  317.       if (br == 8 && mbpf == 1 && wbdd == 1) return(1);
  318.       if (br > 6 && nbpf == 2 && dist_ (wf, wr, bf, 5) <= 1) return(1);
  319.     }
  320.     else
  321.       if (wf == 1 && wr == 8 && bf == 2 && br == 6) return(0);
  322.   }
  323.   mwpf = wf - pf;
  324.   if (mwpf < 0) mwpf = -mwpf;
  325.   if (pr >= 5 && mwpf == 2 && wr == pr && bf == wf && br - pr == 2) return(1);
  326.   brpu = dist_ (bf, br, pf + 1, pr + 1);
  327.   wrpu = dist_ (wf, wr, pf + 1, pr + 1);
  328.   blpu = dist_ (bf, br, pf - 1, pr + 1);
  329.   wlpu = dist_ (wf, wr, pf - 1, pr + 1);
  330.   if (!(pf == 1 || pr != 5))
  331.   { if (mwpf <= 1 && wr - pr == 1) return(1);
  332.     if (wrpu == 1 && brpu > 1) return(1);
  333.     if (wr >= 4 && bf == wf && br - pr >= 2 && mbpf == 3) return(1);
  334.     if (wlpu == 1 && blpu > 1) return(1);
  335.   }
  336.   if (pr == 2 && br == 3 && mbpf > 1 && dist_ (wf, wr, bf, br + 2) <= 1) return(1);
  337.   if (wr - pr == 2 && br == pr && mbpf == 1 && mwpf > 1 &&
  338.       (wf - pf) * (bf - pf) > 0) return(0);
  339.   if (pf == 1 && wf == 1 && wr == br && bf > 3) return(1);
  340.   sgf = pf - 1;
  341.   if (wf >= pf) { sgf = pf + 1; }
  342.   sgr = wr - (mwpf - 1);
  343.   if (mwpf == 0 && wr > br) sgr = wr - 1;
  344.   wsg = dist_ (wf, wr, sgf, sgr);
  345.   if (wr - pr - mwpf > 0 && wr - br >= -1 && bpp - (wsg + (sgr - ppr))
  346.       >= -1 && dist_ (bf, br, sgf, sgr) > wsg) return(1);
  347.   md = mbpf - mwpf;
  348.   if (!(pf != 1 || bf <= 3))
  349.   { sdr = br + (bf - 3);
  350.     if (sdr > 8) sdr = 8;
  351.     if (wr > br + 1) sdr = br;
  352.     if (sdr > ppr)
  353.     { wsd = dist_ (wf, wr, 3, sdr);
  354.       bsd = dist_ (bf, br, 3, sdr);
  355.       if (bsd - wsd < -1) return(0);
  356.       if (bsd <= wsd && md <= 0) return(0);
  357.     }
  358.   }
  359.   brpuuu = dist_ (bf, br, pf + 1, pr + 3);
  360.   if (brpu > wrpu && brpuuu > wrpu && pr - wr != pf - wf) return(1);
  361.   if (brpuuu == 0 && wrpu == 1) return(1);
  362.   blpuuu = dist_ (bf, br, pf - 1, pr + 3);
  363.   if (pf != 1)
  364.   { if (blpu > wlpu && blpuuu > wlpu && pr - wr != wf - pf) return(1);
  365.     if (blpuuu == 0 && wlpu == 1) return(1);
  366.   }
  367.   wrpuu = dist_ (wf, wr, pf + 1, pr + 2);
  368.   if (brpuu > wrpuu) return(1);
  369.   wlpuu = dist_ (wf, wr, pf - 1, pr + 2);
  370.   if (pf > 1 && blpuu > wlpuu) return(1);
  371.   if (br == pr)
  372.   { if (mwpf <= 2 && wr - pr == -1 && mbpf != 2) return(1);
  373.     if (dist_ (wf, wr, bf - 1, br + 2) <= 1 && bf - pf > 1) return(1);
  374.     if (dist_ (wf, wr, bf + 1, br + 2) <= 1 && bf - pf < -1) return(1);
  375.   }
  376.   if (pf != 1)
  377.   { if (br == pr && mbpf > 1 && dist_ (wf, wr, pf, pr - 1) <= 1) return(1);
  378.     if (br - pr >= 3 && wbdd == 1) return(1);
  379.     if (wr - pr >= 2 && wr < br && md >= 0) return(1);
  380.     if (mwpf <= 2 && wr - pr >= 3 && bf != pf && wr - br <= 1) return(1);
  381.     if (wr >= pr && br - pr >= 5 && mbpf >= 3 && md >= -1 && ppr == 3) return(1);
  382.     if (md >= -1 && pr == 2 && br == 8) return(1);
  383.   }
  384.   tbf = bf - 1;
  385.   if (pf > bf) tbf = bf + 1;
  386.   if (mbpf > 1 && br == ppr && dist_ (wf, wr, tbf, wr + 2) <= 1) return(1);
  387.   if (br == pr && bf - pf == -2 && dist_ (wf, wr, pf + 2, pr - 1) <= 1) return(1);
  388.   if (pf > 2 && br == pr && bf - pf == 2 &&
  389.       dist_ (wf, wr, pf - 2, pr - 1) <= 1) return(1);
  390.   return(0);
  391. }                /* kpkwv_ */
  392.  
  393. short 
  394. kpkbv_ (short pf, short pr, short wf, short wr, short bf, short br)
  395. {
  396.   static short incf[8] =
  397.     {0, 1, 1, 1, 0, -1, -1, -1};
  398.   static short incr[8] =
  399.     {1, 1, 0, -1, -1, -1, 0, 1};
  400.  
  401.   short dist_ (short, short, short, short);
  402.   short kpkwv_ (short, short, short, short, short, short);
  403.   static short i, nm, nbf, nbr;
  404.  
  405.   nm = 0;
  406.   for (i = 0; i < 8; ++i)
  407.     {
  408.       nbf = bf + incf[i];
  409.       if (nbf < 1 || nbf > 8) continue;
  410.       nbr = br + incr[i];
  411.       if (nbr < 1 || nbr > 8) continue;
  412.       if (dist_ (nbf, nbr, wf, wr) < 2) continue;
  413.       if (nbf == pf && nbr == pr) return(0);
  414.       if (nbr == pr + 1 && (nbf == pf - 1 || nbf == pf + 1)) continue;
  415.       ++nm;
  416.       if (kpkwv_ (pf, pr, wf, wr, nbf, nbr) == 0) return(0);
  417.     }
  418.   if (nm > 0) return(-1);
  419.   return(0);
  420. }                /* kpkbv_ */
  421.  
  422. short 
  423. dist_ (short f1, short r1, short f2, short r2)
  424. {
  425.   short ts;
  426.   static short fd, rd;
  427.  
  428.   fd = f2 - f1;
  429.   if (fd < 0) fd = -fd;
  430.  
  431.   rd = r2 - r1;
  432.   if (rd < 0) rd = -rd;
  433.  
  434.  ts = ((rd > fd) ? rd : fd);
  435.  return(ts);
  436. }                /* dist_ */
  437.  
  438. inline
  439. int
  440. ScoreK1PK (short side,
  441.        short winner,
  442.        short loser,
  443.        short king1,
  444.        register short king2,
  445.        register short sq)
  446.  
  447.      /*
  448.       *  We call Don Beal's routine with the necessary parameters and determine
  449.       *  win/draw/loss.  Then we compute the real evaluation which is +-500 for
  450.       *  a win/loss and 10 for a draw, plus some points to lead the computer to
  451.       *  a decisive winning/drawing line.
  452.       */
  453.  
  454. {
  455. #ifdef WAY4PL64
  456.   short s;
  457. #endif
  458.   short win, sqc, sqr, k1c, k1r, k2c, k2r;
  459.   const int drawn = 10, won = 500;
  460.  
  461. #ifdef WAY4PL64
  462. #ifdef CACHE
  463.   if (ProbeEETable(side,&s)) return s;
  464. #endif
  465. #endif
  466.   sqc = column (sq) + 1;
  467.   sqr = row (sq) + 1;
  468.   k1c = column (king1) + 1;
  469.   k1r = row (king1) + 1;
  470.   k2c = column (king2) + 1;
  471.   k2r = row (king2) + 1;
  472.   if (winner == black)
  473.     {
  474.       sqr = 9 - sqr;
  475.       k1r = 9 - k1r;
  476.       k2r = 9 - k2r;
  477.     }
  478.   if (sqc > 4)
  479.     {
  480.       sqc = 9 - sqc;
  481.       k1c = 9 - k1c;
  482.       k2c = 9 - k2c;
  483.     }
  484.  
  485.   if (side == winner)
  486.     win = kpkwv_ (sqc, sqr, k1c, k1r, k2c, k2r);
  487.   else
  488.     win = kpkbv_ (sqc, sqr, k1c, k1r, k2c, k2r);
  489.  
  490. #ifdef WAY4PL64
  491.   if (!win)  s = drawn + 5 * distance (sq, king2) - 5*distance(king1,king2);
  492.   else       s = won + 50 * (sqr - 2) + 10*distance(sq,king2);
  493. #else
  494.   if (!win)
  495.     return drawn + 5 * distance (sq, king2);
  496.   else
  497.     return won + 50 * (sqr - 2);
  498. #endif
  499.  
  500. #ifdef WAY4PL64
  501. #ifdef CACHE 
  502.   if (PUTVAR) PutInEETable (side, s); 
  503. #endif 
  504.  
  505.   return s;
  506. #endif
  507. }
  508.  
  509. inline
  510. short
  511. ScoreLoneKing (short side)
  512.  
  513.      /*
  514.       * Static evaluation when loser has only a king and winner has no pawns or no
  515.       * pieces.
  516.       */
  517.  
  518. {
  519. //  short ts;
  520.   register short winner, loser, king1, king2, s, i;
  521.  
  522.   if (mtl[white] == valueK && mtl[black] == valueK)
  523.     return 0;
  524.   UpdateWeights ();
  525.   winner = ((mtl[white] > mtl[black]) ? white : black);
  526.   loser = winner ^ 1;
  527.   king1 = PieceList[winner][0];
  528.   king2 = PieceList[loser][0];
  529.  
  530.   s = 0;
  531.  
  532.   if (pmtl[winner] == 0)
  533.     {
  534.       if (emtl[winner] == valueB + valueN)
  535.     s = ScoreKBNK (winner, king1, king2);
  536.       else if (emtl[winner] == valueN + valueN)
  537.     s = 0;
  538.     else if (emtl[winner] < valueR)
  539.        s = 0;
  540.       else
  541.     s = 500 + emtl[winner] - DyingKing[king2] - 2 * distance (king1, king2);
  542.     }
  543.   else
  544.     {
  545.       if (pmtl[winner] == valueP)
  546.     s = ScoreK1PK (side, winner, loser, king1, king2, PieceList[winner][1]);
  547.       else
  548.     for (i = 1; i <= PieceCnt[winner]; i++)
  549.       s += ScoreKPK (side, winner, loser, king1, king2, PieceList[winner][i]);
  550.     }
  551.   if (side != winner)
  552.     s = 0 - s;
  553.   return(s);
  554. //  ts = ((side == winner) ? s : -s);
  555. //  return (ts);
  556. }
  557.  
  558. #else // old pre 4pl67 code
  559.  
  560. short dist_ (short f1, short r1, short f2, short r2)
  561. {
  562.   return distdata [ f1-9+8*r1 ][ f2-9+8*r2 ];
  563. }
  564.  
  565. short 
  566. kpkwv_ (short pf, short pr, short wf, short wr, short bf, short br)
  567. {
  568.  
  569.   /*
  570.    *  Don Beal's routine, which was originally in Fortran.  See AICC 2
  571.    */
  572.  
  573.  
  574.   const short drawn=0, win=1;
  575.   
  576.   short wbdd, mbpf, blpu;
  577.   short brpu, mwpf, wlpu, wrpu, blpuu, brpuu, wlpuu, wrpuu, md,
  578.     bq, blpuuu, brpuuu, bsd, tbf, sgf, bpp, sdr, sgr, wsd, wsg, ppr, wpp;
  579.  
  580.  
  581.   ppr = pr;
  582.   if (pr == 2) { ppr = 3; }
  583.   if (pf != 1) { goto L2; }
  584.   if (bf != 3) { goto L1; }
  585.   if (pr == 7 && wf == 1 && wr == 8 && br > 6) return drawn;
  586.   if (pr == 6 && wf < 4 && wr == 6 && br == 8) return win;
  587. L1:
  588.   if (bf == 1 && br > pr) return drawn;
  589.   if (pr == 7 && bf > 2) return win;
  590.   if (bf <= 3 && br - ppr > 1) return drawn;
  591.   if (wf == 1 && bf == 3 && wr - pr == 1 && br - pr == 1) return drawn;
  592. L2:
  593.   bq = dist_ (bf, br, pf, 8);
  594.   if (bq > 8 - ppr) return win;
  595.   mbpf = bf - pf;
  596.   if (mbpf < 0) { mbpf = -mbpf; }
  597.   bpp = dist_ (bf, br, pf, ppr);
  598.   wpp = dist_ (wf, wr, pf, ppr);
  599.   if (bpp - wpp < -1 && br - pr != mbpf) return drawn;
  600.   if (pf == 1 && pr <= 3 && wf <= 2 && wr == 8 && bf == 4 && br >= 7) return win;
  601.   if (pf != 2 || pr != 6 || bf != 1 || br != 8) { goto L3; }
  602.   if (wf <= 3 && wr == 6) return drawn;
  603.   if (wf == 4 && wr == 8) return drawn;
  604. L3:
  605.   if (pr != 7) { goto L4; }
  606.   if (wr < 8 && wpp == 2 && bq == 0) return win;
  607.   if (wr == 6 && wf == pf && bq == 0) return win;
  608.   if (wr >= 6 && wpp <= 2 && bq != 0) return win;
  609. L4:
  610.   blpuu = dist_ (bf, br, pf-1, pr+2);
  611.   wbdd = dist_ (wf, wr, bf, br-2);
  612.   brpuu = dist_ (bf, br, pf+1, pr+2);
  613.   if (pr != 6) { goto L6; }
  614.   if (dist_ (bf, br, pf+1, pr) > 1 && brpuu > dist_ (wf, wr, pf+1, pr)) return win;
  615.   if (pf == 1) { goto L5; }
  616.   if (blpuu > dist_ (wf, wr, pf-1, pr)) return win;
  617.   if (br == 8 && mbpf == 1 && wbdd == 1) return win;
  618.   if (br > 6 && mbpf == 2 && dist_ (wf, wr, bf, 5) <= 1) return win;
  619.   goto L6;
  620. L5:
  621.   if (wf == 1 && wr == 8 && bf == 2 && br == 6) return drawn;
  622. L6:
  623.   mwpf = wf - pf;
  624.   if (mwpf < 0) { mwpf = -mwpf; }
  625.   if (pr >= 5 && mwpf == 2 && wr == pr && bf == wf && br - pr == 2) return win;
  626.   brpu = dist_ (bf, br, pf+1, pr+1);
  627.   wrpu = dist_ (wf, wr, pf+1, pr+1);
  628.   blpu = dist_ (bf, br, pf-1, pr+1);
  629.   wlpu = dist_ (wf, wr, pf-1, pr+1);
  630.   if (pf == 1 || pr != 5) { goto L7; }
  631.   if (mwpf <= 1 && wr - pr == 1) return win;
  632.   if (wrpu == 1 && brpu > 1) return win;
  633.   if (wr >= 4 && bf == wf && br - pr >= 2 && mbpf == 3) return win;
  634.   if (wlpu == 1 && blpu > 1) return win;
  635. L7:
  636.   if (pr == 2 && br == 3 && mbpf > 1 && dist_ (wf, wr, bf, br+2) <= 1) return win;
  637.   if (wr - pr == 2 && br == pr && mbpf == 1 && mwpf > 1 && (wf - pf) *
  638.       (bf - pf) > 0) return drawn;
  639.   if (pf == 1 && wf == 1 && wr == br && bf > 3) return win;
  640.   sgf = pf - 1;
  641.   if (wf >= pf) { sgf = pf + 1; }
  642.   sgr = wr - (mwpf - 1);
  643.   if (mwpf == 0 && wr > br) { sgr = wr - 1; }
  644.   wsg = dist_ (wf, wr, sgf, sgr);
  645.   if (wr - pr - mwpf > 0 && wr - br >= -1 && bpp - (wsg + (sgr - ppr))
  646.       >= -1 && dist_ (bf, br, sgf, sgr) > wsg) return win;
  647.   md = mbpf - mwpf;
  648.   if (pf != 1 || bf <= 3) { goto L8; }
  649.   sdr = br + (bf - 3);
  650.   if (sdr > 8) { sdr = 8; }
  651.   if (wr > br + 1) { sdr = br; }
  652.   if (sdr <= ppr) { goto L8; }
  653.   wsd = dist_ (wf, wr, 3, sdr);
  654.   bsd = dist_ (bf, br, 3, sdr);
  655.   if (bsd - wsd < -1) return drawn;
  656.   if (bsd <= wsd && md <= 0) return drawn;
  657. L8:
  658.   brpuuu = dist_ (bf, br, pf+1, pr+3);
  659.   if (brpu > wrpu && brpuuu > wrpu && pr - wr != pf - wf) return win;
  660.   if (brpuuu == 0 && wrpu == 1) return win;
  661.   blpuuu = dist_ (bf, br, pf-1, pr+3);
  662.   if (pf == 1) { goto L9; }
  663.   if (blpu > wlpu && blpuuu > wlpu && pr - wr != wf - pf) return win;
  664.   if (blpuuu == 0 && wlpu == 1) return win;
  665. L9:
  666.   wrpuu = dist_ (wf, wr, pf+1, pr+2);
  667.   if (brpuu > wrpuu) return win;
  668.   wlpuu = dist_ (wf, wr, pf-1, pr+2);
  669.   if (pf > 1 && blpuu > wlpuu) return win;
  670.   if (br != pr) { goto L10; }
  671.   if (mwpf <= 2 && wr - pr == -1 && mbpf != 2) return win;
  672.   if (dist_ (wf, wr, bf-1, br+2) <= 1 && bf - pf > 1) return win;
  673.   if (dist_ (wf, wr, bf+1, br+2) <= 1 && bf - pf < -1) return win;
  674. L10:
  675.   if (pf == 1) { goto L11; }
  676.   if (br == pr && mbpf > 1 && dist_ (wf, wr, pf, pr-1) <= 1) return win;
  677.   if (br - pr >= 3 && wbdd == 1) return win;
  678.   if (wr - pr >= 2 && wr < br && md >= 0) return win;
  679.   if (mwpf <= 2 && wr - pr >= 3 && bf != pf && wr - br <= 1) return win;
  680.   if (wr >= pr && br - pr >= 5 && mbpf >= 3 && md >= -1 && ppr == 3) return win;
  681.   if (md >= -1 && pr == 2 && br == 8) return win;
  682. L11:
  683.   tbf = bf - 1;
  684.   if (pf > bf) { tbf = bf + 1; }
  685.   if (mbpf > 1 && br == ppr && dist_ (wf, wr, tbf, wr+2) <= 1) return win;
  686.   if (br == pr && bf - pf == -2 && dist_ (wf, wr, pf+2, pr-1) <= 1) return win;
  687.   if (pf > 2 && br == pr && bf - pf == 2 && dist_ (wf, wr, pf-2, pr-1) <= 1) return win;
  688.  
  689.   return drawn;
  690. }                /* kpkwv_ */
  691.  
  692. short 
  693. kpkbv_ (short pf, short pr, short wf, short wr, short bf, short br)
  694. {
  695.   /* Initialized data */
  696.  
  697.   static short incf[8] =
  698.   {0, 1, 1, 1, 0, -1, -1, -1};
  699.   static short incr[8] =
  700.   {1, 1, 0, -1, -1, -1, 0, 1};
  701.  
  702.   /* System generated locals */
  703.   short ret_val;
  704.  
  705.   /* Local variables */
  706.   static short i;
  707.   static short nm, nbf, nbr;
  708.  
  709.   ret_val = 0;
  710.   nm = 0;
  711.   for (i = 1; i <= 8; ++i)
  712.     {
  713.       nbf = bf + incf[i - 1];
  714.       if (nbf < 1 || nbf > 8) { goto L1; }
  715.       nbr = br + incr[i - 1];
  716.       if (nbr < 1 || nbr > 8) { goto L1; }
  717.       if (dist_ (nbf, nbr, wf, wr) < 2) { goto L1; }
  718.       if (nbf == pf && nbr == pr) { goto L2; }
  719.       if (nbr == pr + 1 && (nbf == pf - 1 || nbf == pf + 1)) { goto L1; }
  720.       ++nm;
  721.       if (kpkwv_ (pf, pr, wf, wr, nbf, nbr) == 0) { goto L2; }
  722.     L1:
  723.       ;
  724.     }
  725.   if (nm > 0) { ret_val = -1; }
  726. L2:
  727.   return ret_val;
  728. }                /* kpkbv_ */
  729.  
  730.  
  731. inline
  732. int
  733. ScoreK1PK (short int side,
  734.        short int winner,
  735.        short int loser,
  736.        short int king1,
  737.        register short int king2,
  738.        register short int sq)
  739.  
  740.      /*
  741.       *  We call Don Beal's routine with the necessary parameters and determine
  742.       *  win/draw/loss.  Then we compute the real evaluation which is +-500 for
  743.       *  a win/loss and 10 for a draw, plus some points to lead the computer to
  744.       *  a decisive winning/drawing line.
  745.       */
  746.  
  747. {
  748.   short s, win, sqc, sqr, k1c, k1r, k2c, k2r;
  749.   const int drawn = 10, won = 500;
  750.  
  751. #ifdef CACHE
  752.   if (ProbeEETable(side,&s)) return s;
  753. #endif
  754.  
  755.   sqc = column (sq) + 1;
  756.   sqr = row (sq) + 1;
  757.   k1c = column (king1) + 1;
  758.   k1r = row (king1) + 1;
  759.   k2c = column (king2) + 1;
  760.   k2r = row (king2) + 1;
  761.   if (winner == black)
  762.     {
  763.       sqr = 9 - sqr;
  764.       k1r = 9 - k1r;
  765.       k2r = 9 - k2r;
  766.     }
  767.   if (sqc > 4)
  768.     {
  769.       sqc = 9 - sqc;
  770.       k1c = 9 - k1c;
  771.       k2c = 9 - k2c;
  772.     }
  773.  
  774.   if (side == winner) win = kpkwv_ (sqc, sqr, k1c, k1r, k2c, k2r);
  775.   else                win = kpkbv_ (sqc, sqr, k1c, k1r, k2c, k2r);
  776.  
  777.   if (!win)  s = drawn + 5 * distance (sq, king2) - 5*distance(king1,king2);
  778.   else       s = won + 50 * (sqr - 2) + 10*distance(sq,king2);
  779. //  if (!win)  s = drawn + 5 * distance (sq, king2); // old 2.50 way
  780. //  else       s = won + 50 * (sqr - 2); // old 2.50 way
  781.  
  782. #ifdef CACHE 
  783.   if (PUTVAR) PutInEETable (side, s); 
  784. #endif 
  785.  
  786.   return s;
  787. }
  788.  
  789.  
  790. inline
  791. short int
  792. ScoreLoneKing (ARGSZ int side)
  793.  
  794. /*
  795.  * Static evaluation when loser has only a king and winner has no pawns or no
  796.  * pieces.
  797.  */
  798.  
  799. {
  800.     register short winner, loser, king1, king2, s, i;
  801.  
  802.   if (mtl[white] == valueK && mtl[black] == valueK)
  803.     return 0;
  804.     UpdateWeights ();
  805.     winner = ((mtl[white] > mtl[black]) ? white : black);
  806.     loser = winner ^ 1;
  807.     king1 = PieceList[winner][0];
  808.     king2 = PieceList[loser][0];
  809.  
  810.     s = 0;
  811.  
  812.   if (pmtl[winner] == 0)
  813.     {
  814.     if (emtl[winner] == valueB + valueN)
  815.       s = ScoreKBNK (winner, king1, king2);
  816.       else if (emtl[winner] == valueN + valueN || 
  817.                emtl[winner] == valueN || emtl[winner] == valueB)
  818.     s = 0; 
  819.       else
  820.     s = 500 + emtl[winner] - DyingKing[king2] - 2 * distance (king1, king2);
  821.     }
  822.   else {
  823.     if (pmtl[winner] == valueP)
  824.         s = ScoreK1PK (side, winner, loser, king1, king2, PieceList[winner][1]);
  825.       else for (i = 1; i <= PieceCnt[winner]; i++)
  826.         s += ScoreKPK (side, winner, loser, king1, king2, PieceList[winner][i]);
  827.     }
  828.  
  829.     if (side != winner)
  830.      s = 0 - s;
  831.     return(s);
  832. /*    return ((side == winner) ? s : -s);*/
  833. }
  834.  
  835. #endif // old eval pre 4pl67 way
  836.  
  837.  
  838. /* ............    POSITIONAL EVALUATION ROUTINES    ............ */
  839.  
  840. /*
  841.  * Inputs are:
  842.  * pmtl[side] - value of pawns
  843.  * mtl[side]  - value of all material
  844.  * emtl[side] - vaule of all material - value of pawns - value of king
  845.  * hung[side] - count of hung pieces
  846.  * Tscore[ply] - search tree score for ply
  847.  * ply
  848.  * Pscore[ply] - positional score for ply ply
  849.  * INCscore    - bonus score or penalty for certain positions
  850.  * slk - single lone king flag
  851.  * Sdepth - search goal depth
  852.  * xwndw - evaluation window about alpha/beta
  853.  * EWNDW - second evaluation window about alpha/beta
  854.  * ChkFlag[ply]- checking piece at level ply or 0 if no check
  855.  * PC1[column] - # of my pawns in this column
  856.  * PC2[column] - # of opponents pawns in column
  857.  * PieceCnt[side] - just what it says
  858.  */
  859. inline
  860. int
  861. ScoreKPK (short side,
  862.       short winner,
  863.       short loser,
  864.       short king1,
  865.       register short king2,
  866.       register short sq)
  867.  
  868. /*
  869.  * Score King and Pawns versus King endings.
  870.  */
  871.  
  872. {
  873.     register short s, r;
  874.  
  875.     s = ((PieceCnt[winner] == 1) ? 50 : 120);
  876.     if (winner == white)
  877.       {
  878.       r = row (sq) - ((side == loser) ? 1 : 0);
  879.       if (row (king2) >= r && distance (sq, king2) < 8 - r)
  880.           s += 10 * row (sq);
  881.       else
  882.           s = 500 + 50 * row (sq);
  883.       if (row (sq) < 6)
  884.           sq += 16;
  885.       else if (row (sq) == 6)
  886.           sq += 8;
  887.       }
  888.     else
  889.       {
  890.       r = row (sq) + ((side == loser) ? 1 : 0);
  891.       if (row (king2) <= r && distance (sq, king2) < r + 1)
  892.           s += 10 * (7 - row (sq));
  893.       else
  894.           s = 500 + 50 * (7 - row (sq));
  895.       if (row (sq) > 1)
  896.           sq -= 16;
  897.       else if (row (sq) == 1)
  898.           sq -= 8;
  899.       }
  900.     s += 8 * (taxicab (king2, sq) - taxicab (king1, sq));
  901.     return (s);
  902. }
  903.  
  904. inline
  905. int
  906. ScoreKBNK (short winner, short king1, short king2)
  907.  
  908.  
  909. /*
  910.  * Score King+Bishop+Knight versus King endings.  Works fine now.
  911.  */
  912.  
  913. {
  914.     register short s, Bsq, Nsq, KBNKsq = 0;
  915.  
  916.     if (board[PieceList[winner][1]] == bishop)
  917.       {
  918.         Bsq = PieceList[winner][1];
  919.         Nsq = PieceList[winner][2];
  920.       }
  921.     else
  922.       {
  923.         Bsq = PieceList[winner][2];
  924.         Nsq = PieceList[winner][1];
  925.       }
  926.  
  927.     KBNKsq = (((row (Bsq) % 2) == (column (Bsq) % 2)) ? 0 : 7);
  928.  
  929.     s = emtl[winner] - 300;
  930.     s += ((KBNKsq == 0) ? KBNK[king2] : KBNK[locn (row (king2), 7 - column (king2))]);
  931.  
  932. //  The following 2 lines are a fix for this version
  933.    s -= (8*taxicab(king1,king2) + 2*distance(Nsq,king2) + 
  934.                                     distance(Bsq,king2)); 
  935.    s += KingEnding[king1];
  936.     return (s);
  937. }
  938.  
  939. int
  940. evaluate (register short side,
  941.       register short ply,
  942.       register short depth,
  943.           register short ext,
  944.       register short alpha,
  945.       register short beta,
  946.       short INCscore,
  947.       short *InChk)    /* output Check flag */
  948.  
  949. /*
  950.  * Compute an estimate of the score by adding the positional score from the
  951.  * previous ply to the material difference. If this score falls inside a
  952.  * window which is 180 points wider than the alpha-beta window (or within a
  953.  * 50 point window during quiescence search) call ScorePosition() to
  954.  * determine a score, otherwise return the estimated score. If one side has
  955.  * only a king and the other either has no pawns or no pieces then the
  956.  * function ScoreLoneKing() is called.
  957.  */
  958.  
  959. {
  960.     register short xside;
  961.     register short slk;
  962.     short s;
  963.  
  964.     xside = side ^ 1;
  965.     s = -Pscore[ply - 1] + mtl[side] - mtl[xside] - INCscore;
  966.     hung[white] = hung[black] = 0;
  967.     slk = ((mtl[white] == valueK && (pmtl[black] == 0 || emtl[black] == 0)) ||
  968.       (mtl[black] == valueK && (pmtl[white] == 0 || emtl[white] == 0)));
  969.  
  970.           /* should we use the estimete or score the position */
  971.     if ( !slk && (ply == 1 ||
  972. #ifdef CACHE
  973.         (CheckEETable (side)) ||
  974. #endif
  975.         (myneweval ? ((
  976.         (ply==Sdepth || (!ext && depth == 0 && s>=alpha-30 && s<=beta+30)) ||
  977.         (ext && (s >= (alpha - 30) && s <= (beta + 30)) )) )
  978.         :
  979.         ((Sdepth ==  ply) ||
  980.         (ply > Sdepth && (s >= (alpha - 30) && s <= (beta + 30)) )) )
  981.         ))
  982.  
  983.       {
  984.       /* score the position */
  985.       ataks (side, atak[side]);
  986.       if (Anyatak (side, PieceList[xside][0])){
  987.       ataks (xside, atak[xside]);
  988.       ChkFlag[ply-1] = *InChk = (Anyatak (xside, PieceList[side][0]))?(Pindex[TOsquare]+1):0;
  989.           return (10001 - ply);
  990.       }
  991.       ataks (xside, atak[xside]);
  992.       ChkFlag[ply-1] = *InChk = (Anyatak (xside, PieceList[side][0]))?(Pindex[TOsquare]+1):0;
  993.  
  994. #ifndef BAREBONES 
  995.       EvalNodes++;
  996. #endif
  997.     if(ply>4)PUTVAR=true;
  998.           s = ScorePosition (side);
  999.     PUTVAR=false;
  1000.       }
  1001.     else
  1002.       {
  1003.       /* use the estimate but look at check and slk */
  1004.        *InChk = SqAtakd (PieceList[side][0], xside);
  1005.        ChkFlag[ply - 1] = ((*InChk) ? Pindex[TOsquare] + 1 : 0);
  1006.        if (SqAtakd (PieceList[xside][0], side)){ return (10001 - ply); }
  1007. #ifdef DEBUG 
  1008.        if(debuglevel & 4096){
  1009.       printf("%lx %lx %d %d\n",hashbd,hashkey,ply,s);
  1010.       }
  1011. #endif
  1012.       if (slk){
  1013.         if(ply>4)PUTVAR=true;
  1014.               s = ScoreLoneKing (side);
  1015.         PUTVAR=false;}
  1016.       }
  1017.  
  1018.     Pscore[ply] = s - mtl[side] + mtl[xside];
  1019.     ChkFlag[ply - 1] = ((*InChk) ? Pindex[TOsquare] + 1 : 0);
  1020.     QueenCheck[ply - 1] =       /* tom@izf.tno.nl */
  1021.           ((*InChk) && board[TOsquare] == queen) ? TOsquare : 0;
  1022. #ifdef DEBUG 
  1023.        if(debuglevel & 4096){
  1024.     printf("%lx %lx %d %d\n",hashbd,hashkey,ply,s);
  1025.     }
  1026. #endif
  1027.     return (s);
  1028. }
  1029.  
  1030. inline
  1031. int
  1032. BRscan (register short sq, short *mob)
  1033.  
  1034. /*
  1035.  * Find Bishop and Rook mobility, XRAY attacks, and pins. Increment the
  1036.  * hung[] array if a pin is found.
  1037.  */
  1038. {
  1039.     register unsigned char *ppos, *pdir;
  1040.     register short s, mobx;
  1041.     register short u, pin;
  1042.     short piece, *Kf;
  1043.     mobx = s = 0;
  1044.     Kf = Kfield[c1];
  1045.     piece = board[sq];
  1046.     ppos = nextpos[piece][sq];
  1047.     pdir = nextdir[piece][sq];
  1048.     u = ppos[sq];
  1049.     pin = -1;            /* start new direction */
  1050.     do
  1051.       {
  1052.       s += Kf[u];
  1053.       if (color[u] == neutral)
  1054.         {
  1055.         mobx++;
  1056.         if (ppos[u] == pdir[u])
  1057.             pin = -1;    /* oops new direction */
  1058.         u = ppos[u];
  1059.         }
  1060.       else if (pin < 0)
  1061.         {
  1062.         if (board[u] == pawn || board[u] == king)
  1063.             u = pdir[u];
  1064.         else
  1065.           {
  1066.               if (ppos[u] != pdir[u])
  1067.               pin = u;    /* not on the edge and on to find a pin */
  1068.               u = ppos[u];
  1069.           }
  1070.         }
  1071.       else
  1072.         {
  1073.         if (color[u] == c2 && (board[u] > piece || atk2[u] == 0))
  1074.           {
  1075.               if (color[pin] == c2)
  1076.             {
  1077.                 s += PINVAL;
  1078.                 if (atk2[pin] == 0 || atk1[pin] > control[board[pin]] + 1)
  1079.                 ++hung[c2];
  1080.             }
  1081.               else
  1082.               s += XRAY;
  1083.           }
  1084.         pin = -1;    /* new direction */
  1085.         u = pdir[u];
  1086.         }
  1087.       }
  1088.     while (u != sq);
  1089.     *mob = mobx;
  1090.     return s;
  1091. }
  1092.  
  1093. inline
  1094. short
  1095. KingScan (register short sq)
  1096.  
  1097. /*
  1098.  * Assign penalties if king can be threatened by checks, if squares near the
  1099.  * king are controlled by the enemy (especially the queen), or if there are
  1100.  * no pawns near the king. 
  1101.     The following must be true: 
  1102.         board[sq] == king 
  1103.         c1 == color[sq] 
  1104.         c2 == otherside[c1]
  1105.  */
  1106.  
  1107. #define ScoreThreat \
  1108.     if (color[u] != c2)\
  1109.       if (atk1[u] == 0 || (atk2[u] & 0xFF) > 1) ++cnt;\
  1110.       else s -= 3
  1111.  
  1112. {
  1113.     register short cnt;
  1114.     register unsigned char *ppos, *pdir;
  1115.     register short s;
  1116.     register short u;
  1117.     short ok;
  1118.  
  1119.     s = 0;
  1120.     cnt = 0;
  1121.     if (HasBishop[c2] || HasQueen[c2])
  1122.       {
  1123.       ppos = nextpos[bishop][sq];
  1124.       pdir = nextdir[bishop][sq];
  1125.       u = ppos[sq];
  1126.       do
  1127.         {
  1128.         if (atk2[u] & ctlBQ)
  1129.             ScoreThreat;
  1130.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  1131.         }
  1132.       while (u != sq);
  1133.       }
  1134.     if (HasRook[c2] || HasQueen[c2])
  1135.       {
  1136.       ppos = nextpos[rook][sq];
  1137.       pdir = nextdir[rook][sq];
  1138.       u = ppos[sq];
  1139.       do
  1140.         {
  1141.         if (atk2[u] & ctlRQ)
  1142.             ScoreThreat;
  1143.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  1144.         }
  1145.       while (u != sq);
  1146.       }
  1147.     if (HasKnight[c2])
  1148.       {
  1149.       pdir = nextdir[knight][sq];
  1150.       u = pdir[sq];
  1151.       do
  1152.         {
  1153.         if (atk2[u] & ctlNN)
  1154.             ScoreThreat;
  1155.         u = pdir[u];
  1156.         }
  1157.       while (u != sq);
  1158.       }
  1159.     s += (KSFTY * KTHRT[cnt]) / 16;
  1160.  
  1161.     cnt = 0;
  1162.     ok = false;
  1163.     pdir = nextpos[king][sq];
  1164.     u = pdir[sq];
  1165.     do
  1166.       {
  1167.       if (board[u] == pawn)
  1168.           ok = true;
  1169.       if (atk2[u] > atk1[u])
  1170.         {
  1171.         ++cnt;
  1172.         if (atk2[u] & ctlQ)
  1173.             if (atk2[u] > ctlQ + 1 && atk1[u] < ctlQ)
  1174.             s -= 4 * KSFTY;
  1175.         }
  1176.       u = pdir[u];
  1177.       }
  1178.     while (u != sq);
  1179.     if (!ok)
  1180.     s -= KSFTY;
  1181.     if (cnt > 1)
  1182.     s -= (KSFTY);
  1183.     return (s);
  1184. }
  1185.  
  1186. inline
  1187. int
  1188. trapped (register short sq)
  1189.  
  1190. /*
  1191.  * See if the attacked piece has unattacked squares to move to. The following
  1192.  * must be true: c1 == color[sq] c2 == otherside[c1]
  1193.  */
  1194.  
  1195. {
  1196.     register short u;
  1197.     register unsigned char *ppos, *pdir;
  1198.     register short piece;
  1199.  
  1200.     piece = board[sq];
  1201.     ppos = nextpos[ptype[c1][piece]][sq];
  1202.     pdir = nextdir[ptype[c1][piece]][sq];
  1203.     if (piece == pawn)
  1204.       {
  1205.       u = ppos[sq];        /* follow no captures thread */
  1206.       if (color[u] == neutral)
  1207.         {
  1208.         if (atk1[u] >= atk2[u])
  1209.             return (false);
  1210.         if (atk2[u] < ctlP)
  1211.           {
  1212.               u = ppos[u];
  1213.               if (color[u] == neutral && atk1[u] >= atk2[u])
  1214.               return (false);
  1215.           }
  1216.         }
  1217.       u = pdir[sq];        /* follow captures thread */
  1218.       if (color[u] == c2)
  1219.           return (false);
  1220.       u = pdir[u];
  1221.       if (color[u] == c2)
  1222.           return (false);
  1223.       }
  1224.     else
  1225.       {
  1226.       u = ppos[sq];
  1227.       do
  1228.         {
  1229.         if (color[u] != c1)
  1230.             if (atk2[u] == 0 || board[u] >= piece)
  1231.             return (false);
  1232.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  1233.         }
  1234.       while (u != sq);
  1235.       }
  1236.     return (true);
  1237. }
  1238.  
  1239.  
  1240.  
  1241. //#define PAWNVALUE_4PL69 1
  1242. #ifdef PAWNVALUE_4PL69
  1243. // this is PawnValue from 4PL69
  1244. static inline int
  1245. PawnValue (register short sq, short side)
  1246. /*
  1247.  * Calculate the positional value for a pawn on 'sq'.
  1248.  */
  1249. {
  1250.     register short fyle, rank;
  1251.     register short j, s, a1, a2, in_square, r, e;
  1252.  
  1253.     a1 = (atk1[sq] & 0x4FFF);
  1254.     a2 = (atk2[sq] & 0x4FFF);
  1255.     rank = row (sq);
  1256.     fyle = column (sq);
  1257.     s = 0;
  1258.     if (c1 == white)
  1259.       {
  1260.       s = Mwpawn[sq];
  1261.       if ((sq == 11 && color[19] != neutral) || (sq == 12 && color[20] != neutral)) s += PEDRNK2B;
  1262.       if ((fyle == 0 || PC1[fyle - 1] == 0) && (fyle == 7 || PC1[fyle + 1] == 0)) s += ISOLANI[fyle];
  1263.       else if (PC1[fyle] > 1) s += PDOUBLED;
  1264.  
  1265.       if ((atk2[sq+8] & ctlP) && !(a1 & ctlP) && !(atk1[sq+8] & ctlP))
  1266.         {
  1267.         s += BACKWARD[a2 & 0xFF];
  1268.         if (PC2[fyle] == 0) s += PWEAKH;
  1269.         if (color[sq + 8] != neutral) s += PBLOK;
  1270.         }
  1271.       if(rank != 7 && color[sq+8] == black && board[sq+8] == pawn) s -= PCRASH;
  1272.       if (PC2[fyle] == 0)
  1273.         {
  1274.         r = rank - ((side == black)?1:0);
  1275.         in_square = (row (bking) >= r && distance (sq, bking) < 8 - r);
  1276.         e = (a2 == 0 || side == white)? 0:1;
  1277.         for (j = sq + 8; j < 64; j += 8)
  1278.             if (atk2[j] >= ctlP) { e = 2; break; }
  1279.             else if (atk2[j] > 0 || color[j] != neutral) e = 1;
  1280.  
  1281.         if (e == 2) s += (stage * PassedPawn3[rank]) / 10;
  1282.         else if (in_square || e == 1) s += (stage * PassedPawn2[rank]) / 10;
  1283.         else if (emtl[black] > 0) s += (stage * PassedPawn1[rank]) / 10;
  1284.         else s += PassedPawn0[rank];
  1285.         }
  1286.       }
  1287.     else if (c1 == black)
  1288.       {
  1289.       s = Mbpawn[sq];
  1290.       if ((sq == 51 && color[43] != neutral) || (sq == 52 && color[44] != neutral)) s += PEDRNK2B;
  1291.  
  1292.       if ((fyle == 0 || PC1[fyle - 1] == 0) && (fyle == 7 || PC1[fyle + 1] == 0)) s += ISOLANI[fyle];
  1293.       else if (PC1[fyle] > 1) s += PDOUBLED;
  1294.  
  1295.       if ((atk2[sq-8] & ctlP) && !(a1 & ctlP) && !(atk1[sq-8] & ctlP))
  1296.         {
  1297.         s += BACKWARD[a2 & 0xFF];
  1298.         if (PC2[fyle] == 0) s += PWEAKH;
  1299.         if (color[sq - 8] != neutral) s += PBLOK;
  1300.         }
  1301.       if(rank != 0 && color[sq-8] == white && board[sq-8] == pawn) s -= PCRASH;
  1302.       if (PC2[fyle] == 0)
  1303.         {
  1304.         r = rank + ((side == white)?1:0);
  1305.         in_square = (row (wking) <= r && distance (sq, wking) < r + 1);
  1306.         e = (a2 == 0 || side == black)?0:1;
  1307.         for (j = sq - 8; j >= 0; j -= 8)
  1308.             if (atk2[j] >= ctlP) { e = 2; break; }
  1309.             else if (atk2[j] > 0 || color[j] != neutral) e = 1;
  1310.  
  1311.         if (e == 2) s += (stage * PassedPawn3[7 - rank]) / 10;
  1312.         else if (in_square || e == 1) s += (stage * PassedPawn2[7 - rank]) / 10;
  1313.         else if (emtl[white] > 0) s += (stage * PassedPawn1[7 - rank]) / 10;
  1314.         else s += PassedPawn0[7 - rank];
  1315.         }
  1316.       }
  1317.     if((rank >2 && rank < 6) && (fyle > 2 && fyle < 5)) s += PCENTER;
  1318.     if (a2 > 0)
  1319.       {
  1320.       if (a1 == 0 || a2 > ctlP + 1)
  1321.         {
  1322.         s += HUNGP;
  1323.         if (trapped (sq)) hung[c1] += 2;
  1324.         hung[c1]++;
  1325.         }
  1326.       else if (a2 > a1) s += ATAKD;
  1327.       }
  1328.     return (s);
  1329. }
  1330. #else // this is Pawn value from 4PL70
  1331. // from 4pl70
  1332. inline int
  1333. PawnValue (register short sq, short side)
  1334. /*
  1335.  * Calculate the positional value for a pawn on 'sq'.
  1336.  */
  1337.  
  1338. {
  1339.     register short fyle, rank;
  1340.     register short j, s, a1, a2, in_square, r, e;
  1341.  
  1342.     a1 = (atk1[sq] & 0x4FFF);
  1343.     a2 = (atk2[sq] & 0x4FFF);
  1344.     rank = row (sq);
  1345.     fyle = column (sq);
  1346.     s = 0;
  1347.     if (c1 == white)
  1348.       {
  1349.       s = Mwpawn[sq];
  1350.       if ((sq == 11 && color[19] != neutral) || (sq == 12 && color[20] != neutral)) s += PEDRNK2B;
  1351.       if ((fyle == 0 || PC1[fyle - 1] == 0) && (fyle == 7 || PC1[fyle + 1] == 0)) s += ISOLANI[fyle];
  1352.       else if (PC1[fyle] > 1) s += PDOUBLED;
  1353.  
  1354.       if (a1 < ctlP && atk1[sq + 8] < ctlP)
  1355.         {
  1356.         s += BACKWARD[a2 & 0xFF];
  1357.         if (PC2[fyle] == 0) s += PWEAKH;
  1358.         if (color[sq + 8] != neutral) s += PBLOK;
  1359.         }
  1360.       if(c1 == computer && rank != 7 && 
  1361.              color[sq+8] == black && board[sq+8] == pawn) s -= PCRASH;
  1362.       if (PC2[fyle] == 0)
  1363.         {
  1364.         r = rank - ((side == black)?1:0);
  1365.         in_square = (row (bking) >= r && distance (sq, bking) < 8 - r);
  1366.         e = (a2 == 0 || side == white)? 0:1;
  1367.         for (j = sq + 8; j < 64; j += 8)
  1368.             if (atk2[j] >= ctlP) { e = 2; break; }
  1369.             else if (atk2[j] > 0 || color[j] != neutral) e = 1;
  1370.  
  1371.         if (e == 2) s += (stage * PassedPawn3[rank]) / 10;
  1372.         else if (in_square || e == 1) s += (stage * PassedPawn2[rank]) / 10;
  1373.         else if (emtl[black] > 0) s += (stage * PassedPawn1[rank]) / 10;
  1374.         else s += PassedPawn0[rank];
  1375.         }
  1376.       }
  1377.     else if (c1 == black)
  1378.       {
  1379.       s = Mbpawn[sq];
  1380.       if ((sq == 51 && color[43] != neutral) || (sq == 52 && color[44] != neutral)) s += PEDRNK2B;
  1381.  
  1382.       if ((fyle == 0 || PC1[fyle - 1] == 0) && (fyle == 7 || PC1[fyle + 1] == 0)) s += ISOLANI[fyle];
  1383.       else if (PC1[fyle] > 1) s += PDOUBLED;
  1384.  
  1385.       if (a1 < ctlP && atk1[sq - 8] < ctlP)
  1386.         {
  1387.         s += BACKWARD[a2 & 0xFF];
  1388.         if (PC2[fyle] == 0) s += PWEAKH;
  1389.         if (color[sq - 8] != neutral) s += PBLOK;
  1390.         }
  1391.       if(c1 == computer && rank != 0 && 
  1392.              color[sq-8] == white && board[sq-8] == pawn) s -= PCRASH;
  1393.       if (PC2[fyle] == 0)
  1394.         {
  1395.         r = rank + ((side == white)?1:0);
  1396.         in_square = (row (wking) <= r && distance (sq, wking) < r + 1);
  1397.         e = (a2 == 0 || side == black)?0:1;
  1398.         for (j = sq - 8; j >= 0; j -= 8)
  1399.             if (atk2[j] >= ctlP) { e = 2; break; }
  1400.             else if (atk2[j] > 0 || color[j] != neutral) e = 1;
  1401.  
  1402.         if (e == 2) s += (stage * PassedPawn3[7 - rank]) / 10;
  1403.         else if (in_square || e == 1) s += (stage * PassedPawn2[7 - rank]) / 10;
  1404.         else if (emtl[white] > 0) s += (stage * PassedPawn1[7 - rank]) / 10;
  1405.         else s += PassedPawn0[7 - rank];
  1406.         }
  1407.       }
  1408.     if((rank >2 && rank < 6) && (fyle > 2 && fyle < 5)) s += PCENTER;
  1409.     if (a2 > 0)
  1410.       {
  1411.       if (a1 == 0 || a2 > ctlP + 1)
  1412.         {
  1413.         s += HUNGP;
  1414.         if (trapped (sq)) hung[c1] += 2;
  1415.         hung[c1]++;
  1416.         }
  1417.       else if (a2 > a1) s += ATAKD;
  1418.       }
  1419.     return (s);
  1420. }
  1421. #endif // panwvalue from 4pl69 or 4pl68
  1422.  
  1423.  
  1424. inline
  1425. int
  1426. KnightValue (register short sq, short side)
  1427.  
  1428. /*
  1429.  * Calculate the positional value for a knight on 'sq'.
  1430.  */
  1431.  
  1432. {
  1433.     register short s, a2, a1;
  1434.  
  1435.     s = Mknight[c1][sq];
  1436.     a2 = (atk2[sq] & 0x4FFF);
  1437.     if (a2 > 0)
  1438.       {
  1439.       a1 = (atk1[sq] & 0x4FFF);
  1440.       if (a1 == 0 || a2 > ctlBN + 1)
  1441.         {
  1442.         s += HUNGP;
  1443.         if (trapped (sq))
  1444.             hung[c1] += 2;
  1445.         hung[c1]++;
  1446.         }
  1447.       else if (a2 >= ctlBN || a1 < ctlP)
  1448.           s += ATAKD;
  1449.       }
  1450.     return (s);
  1451. }
  1452.  
  1453. inline
  1454. int
  1455. BishopValue (register short sq, short side)
  1456.  
  1457. /*
  1458.  * Calculate the positional value for a bishop on 'sq'.
  1459.  */
  1460.  
  1461. {
  1462.     register short s;
  1463.     register short a2, a1;
  1464.     short mob;
  1465.  
  1466.     s = Mbishop[c1][sq];
  1467.     s += BRscan (sq, &mob);
  1468.     s += BMBLTY[mob];
  1469.     a2 = (atk2[sq] & 0x4FFF);
  1470.     if (a2 > 0)
  1471.       {
  1472.       a1 = (atk1[sq] & 0x4FFF);
  1473.       if (a1 == 0 || a2 > ctlBN + 1)
  1474.         {
  1475.         s += HUNGP;
  1476.         if (trapped (sq))
  1477.             hung[c1] += 2;
  1478.         hung[c1]++;
  1479.         }
  1480.       else if (a2 >= ctlBN || a1 < ctlP)
  1481.           s += ATAKD;
  1482.       }
  1483.     return (s);
  1484. }
  1485.  
  1486. inline
  1487. int
  1488. RookValue (register short sq, short side)
  1489.  
  1490. /*
  1491.  * Calculate the positional value for a rook on 'sq'.
  1492.  */
  1493.  
  1494. {
  1495.     register short s;
  1496.     register short fyle, a2, a1;
  1497.     short mob;
  1498.  
  1499.     s = RookBonus;
  1500.     s += BRscan (sq, &mob);
  1501.     s += RMBLTY[mob];
  1502.     fyle = column (sq);
  1503.     if (PC1[fyle] == 0)
  1504.     { s += RHOPN;
  1505.             if (PC2[fyle] == 0)
  1506.             s += RHOPNX;
  1507.         }
  1508.     if (pmtl[c2] > 100 && row (sq) == rank7[c1])
  1509.     s += 10;
  1510.     if (stage > 2)
  1511.     s += 14 - taxicab (sq, EnemyKing);
  1512.     a2 = (atk2[sq] & 0x4FFF);
  1513.     if (a2 > 0)
  1514.       {
  1515.       a1 = (atk1[sq] & 0x4FFF);
  1516.       if (a1 == 0 || a2 > ctlR + 1)
  1517.         {
  1518.         s += HUNGP;
  1519.         if (trapped (sq))
  1520.             hung[c1] += 2;
  1521.         hung[c1]++;
  1522.         }
  1523.       else if (a2 >= ctlR || a1 < ctlP)
  1524.           s += ATAKD;
  1525.       }
  1526.     return (s);
  1527. }
  1528.  
  1529. inline
  1530. int
  1531. QueenValue (register short sq, short side)
  1532.  
  1533. /*
  1534.  * Calculate the positional value for a queen on 'sq'.
  1535.  */
  1536.  
  1537. {
  1538.     register short s, a2, a1;
  1539.  
  1540.     s = ((distance (sq, EnemyKing) < 3) ? 12 : 0);
  1541.     if (stage > 2)
  1542.     s += 14 - taxicab (sq, EnemyKing);
  1543.     a2 = (atk2[sq] & 0x4FFF);
  1544.     if (a2 > 0)
  1545.       {
  1546.       a1 = (atk1[sq] & 0x4FFF);
  1547.       if (a1 == 0 || a2 > ctlQ + 1)
  1548.         {
  1549.         s += HUNGP;
  1550.         if (trapped (sq))
  1551.             hung[c1] += 2;
  1552.         hung[c1]++;
  1553.         }
  1554.       else if (a2 >= ctlQ || a1 < ctlP)
  1555.           s += ATAKD;
  1556.       }
  1557.     return (s);
  1558. }
  1559.  
  1560. #define WAY4PL71 // for AHOPEN mods
  1561. inline
  1562. int
  1563. KingValue (register short sq, short side)
  1564.  
  1565. /*
  1566.  * Calculate the positional value for a king on 'sq'.
  1567.  */
  1568. {
  1569.     register short s;
  1570.     register short fyle;
  1571.     short a2, a1;
  1572.     s = (emtl[c2] > KINGPOSLIMIT) ? Mking[c1][sq] : Mking[c1][sq] / 2;
  1573.     if (KSFTY > 0)
  1574.     if (Developed[c2] || stage > 0)
  1575.         s += KingScan (sq);
  1576.     if (castld[c1])
  1577.     s += KCASTLD;
  1578.     else if (Mvboard[kingP[c1]])
  1579.     s += KMOVD;
  1580.  
  1581.     fyle = column (sq);
  1582.     if (PC1[fyle] == 0)
  1583.     s += KHOPN;
  1584.     if (PC2[fyle] == 0)
  1585.     s += KHOPNX;
  1586. #ifdef WAY4PL71
  1587.     switch (fyle)
  1588.       {
  1589.       case 5:
  1590.       if (PC1[7] == 0)
  1591.           s += KHOPN;
  1592.       if (PC2[7] == 0)
  1593.           s += KHOPNX;
  1594.       /* Fall through */
  1595.       case 6:
  1596.       //if(HasQueen[c2])if (PC1[7] == 0) s += AHOPEN;
  1597.       case 4:
  1598.       case 0:
  1599.  
  1600.       if (PC1[fyle + 1] == 0)
  1601.           s += KHOPN;
  1602.       if (PC2[fyle + 1] == 0)
  1603.           s += KHOPNX;
  1604.       break;
  1605.       case 2:
  1606.       if (PC1[0] == 0)
  1607.           s += KHOPN;
  1608.       if (PC2[0] == 0)
  1609.           s += KHOPNX;
  1610.       /* Fall through */
  1611.       case 1:
  1612.       //if(HasQueen[c2])if (PC1[0] == 0) s += AHOPEN;
  1613.       case 3:
  1614.       case 7:
  1615.       if (PC1[fyle - 1] == 0)
  1616.           s += KHOPN;
  1617.       if (PC2[fyle - 1] == 0)
  1618.           s += KHOPNX;
  1619.       break;
  1620.       default:
  1621.       /* Impossible! */
  1622.       break;
  1623.       }
  1624.     /*  Some extra code for Ng5 problem */
  1625.     if (computer==c1 && fyle >= 6 && HasQueen[c2] && PC1[7]==0)
  1626.       s += AHOPEN;
  1627.     if (computer==c1 && fyle <= 1 && HasQueen[c2] && PC1[0]==0)
  1628.       s += AHOPEN;
  1629. #else // this is the 4pl69 way
  1630.     switch (fyle)
  1631.       {
  1632.       case 5:
  1633.       if (PC1[7] == 0)
  1634.           s += KHOPN;
  1635.       if (PC2[7] == 0)
  1636.           s += KHOPNX;
  1637.       /* Fall through */
  1638.       case 4:
  1639.       case 6:
  1640.       case 0:
  1641.       if (PC1[fyle + 1] == 0)
  1642.           s += KHOPN;
  1643.       if (PC2[fyle + 1] == 0)
  1644.           s += KHOPNX;
  1645.       break;
  1646.       case 2:
  1647.       if (PC1[0] == 0)
  1648.           s += KHOPN;
  1649.       if (PC2[0] == 0)
  1650.           s += KHOPNX;
  1651.       /* Fall through */
  1652.       case 3:
  1653.       case 1:
  1654.       case 7:
  1655.       if (PC1[fyle - 1] == 0)
  1656.           s += KHOPN;
  1657.       if (PC2[fyle - 1] == 0)
  1658.           s += KHOPNX;
  1659.       break;
  1660.       default:
  1661.       /* Impossible! */
  1662.       break;
  1663.       }
  1664. #endif
  1665.  
  1666.     a2 = (atk2[sq] & 0x4FFF);
  1667.     if (a2 > 0)
  1668.       {
  1669.       a1 = (atk1[sq] & 0x4FFF);
  1670.       if (a1 == 0 || a2 > ctlK + 1)
  1671.         {
  1672.         s += HUNGP;
  1673.         ++hung[c1];
  1674.         }
  1675.       else
  1676.           s += ATAKD;
  1677.       }
  1678.     return (s);
  1679. }
  1680.  
  1681.  
  1682.  
  1683. short
  1684. ScorePosition (register short side)
  1685.  
  1686. /*
  1687.  * Perform normal static evaluation of board position. A score is generated
  1688.  * for each piece and these are summed to get a score for each side.
  1689.  */
  1690.  
  1691. {
  1692.     register short score;
  1693.     register short sq, i, xside;
  1694.     short s;
  1695.  
  1696.     UpdateWeights ();
  1697.     xside = side ^ 1;
  1698.     hung[white] = hung[black] = pscore[white] = pscore[black] = 0;
  1699. #ifdef CACHE
  1700.     if (!(hashkey+hashbd) || !ProbeEETable (side, &s))
  1701.       {
  1702. #endif
  1703.       for (c1 = white; c1 <= black; c1++)
  1704.         {
  1705.         c2 = c1 ^ 1;
  1706.         /* atk1 is array of atacks on squares by my side */
  1707.         atk1 = atak[c1];
  1708.         /* atk2 is array of atacks on squares by other side */
  1709.         atk2 = atak[c2];
  1710.         /* same for PC1 and PC2 */
  1711.         PC1 = PawnCnt[c1];
  1712.         PC2 = PawnCnt[c2];
  1713.         for (i = PieceCnt[c1]; i >= 0; i--)
  1714.           {
  1715.               sq = PieceList[c1][i];
  1716.               switch (board[sq])
  1717.             {
  1718.             case pawn:
  1719.                 s = PawnValue (sq, side);
  1720.                 break;
  1721.             case knight:
  1722.                 s = KnightValue (sq, side);
  1723.                 break;
  1724.             case bishop:
  1725.                 s = BishopValue (sq, side);
  1726.                 break;
  1727.             case rook:
  1728.                 s = RookValue (sq, side);
  1729.                 break;
  1730.             case queen:
  1731.                 s = QueenValue (sq, side);
  1732.                 break;
  1733.             case king:
  1734.                 s = KingValue (sq, side);
  1735.                 break;
  1736.             default:
  1737.                 s = 0;
  1738.                 break;
  1739.             }
  1740.               pscore[c1] += s;
  1741.               svalue[sq] = s;
  1742.           }
  1743.         }
  1744.     if (hung[side] > 1)
  1745.     pscore[side] += HUNGX;
  1746.     if (hung[xside] > 1)
  1747.     pscore[xside] += HUNGX;
  1748.  
  1749.     score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10;
  1750. #ifndef NODITHER
  1751.     if (dither)
  1752.       {
  1753.       if (flag.hash)
  1754.           gsrand (starttime + (unsigned int) hashbd);
  1755.       score += urand () % dither;
  1756.       }
  1757. #endif
  1758.     if (score > 0 && pmtl[side] == 0)
  1759.     if (emtl[side] < valueR)
  1760.         score = 0;
  1761.     else if (score < valueR)
  1762.         score /= 2;
  1763.     if (score < 0 && pmtl[xside] == 0)
  1764.     if (emtl[xside] < valueR)
  1765.         score = 0;
  1766.     else if (-score < valueR)
  1767.         score /= 2;
  1768.  
  1769.     if (mtl[xside] == valueK && emtl[side] > valueB)
  1770.     score += 200;
  1771.     if (mtl[side] == valueK && emtl[xside] > valueB)
  1772.     score -= 200;
  1773. #ifdef CACHE
  1774.     if(PUTVAR)PutInEETable(side,score);
  1775. #endif
  1776.     return (score);
  1777. #ifdef CACHE
  1778. }
  1779. else {
  1780. return s;
  1781. }
  1782. #endif
  1783. }
  1784.  
  1785.  
  1786.  
  1787. static inline void
  1788. BlendBoard (const short a[64], const short b[64], short c[64])
  1789. {
  1790.     register int sq, s;
  1791.     s = 10 - stage;
  1792.     for (sq = 0; sq < 64; sq++)
  1793.     c[sq] = ((a[sq] * s) + (b[sq] * stage)) / 10;
  1794. }
  1795.  
  1796.  
  1797. static inline void
  1798. CopyBoard (const short a[64], short b[64])
  1799. {
  1800. #ifndef AMIGA
  1801.     register short *sqa, *sqb;
  1802.  
  1803.     for (sqa = (short *)a, sqb = b; sqa < a + 64;)
  1804.     *sqb++ = *sqa++;
  1805. #else
  1806.  MoveMem128(a,b);
  1807. /* MoveMem(a,b,64*sizeof(short));*/
  1808. #endif
  1809. }
  1810.  
  1811.  
  1812. short __aligned PawnStorm = false;
  1813.  
  1814. void
  1815. ExaminePosition (void)
  1816.  
  1817. /*
  1818.  * This is done one time before the search is started. Set up arrays Mwpawn,
  1819.  * Mbpawn, Mknight, Mbishop, Mking which are used in the SqValue() function
  1820.  * to determine the positional value of each piece.
  1821.  */
  1822.  
  1823. {
  1824.     register short i, sq;
  1825.     register short fyle;
  1826.     short wpadv, bpadv, wstrong, bstrong, z, side, pp, j, k, val, Pd, rank;
  1827. /* update ataks arrays */
  1828.     ataks (white, atak[white]);
  1829.     ataks (black, atak[black]);
  1830. /*    */
  1831.     UpdateWeights ();
  1832. /* initialize Hasxxx */
  1833.     HasKnight[white] = HasKnight[black] = 0;
  1834.     HasBishop[white] = HasBishop[black] = 0;
  1835.     HasRook[white] = HasRook[black] = 0;
  1836.     HasQueen[white] = HasQueen[black] = 0;
  1837.     for (side = white; side <= black; side++)
  1838.     for (i = PieceCnt[side]; i >= 0; i--)
  1839.         switch (board[PieceList[side][i]])
  1840.           {
  1841.           case knight:
  1842.           ++HasKnight[side];
  1843.           break;
  1844.           case bishop:
  1845.           ++HasBishop[side];
  1846.           break;
  1847.           case rook:
  1848.           ++HasRook[side];
  1849.           break;
  1850.           case queen:
  1851.           ++HasQueen[side];
  1852.           break;
  1853.           }
  1854. /* Developed if has moved knights and bishops */
  1855.     if (!Developed[white])
  1856.     Developed[white] = (board[1] != knight && board[2] != bishop &&
  1857.                 board[5] != bishop && board[6] != knight);
  1858.     if (!Developed[black])
  1859.     Developed[black] = (board[57] != knight && board[58] != bishop &&
  1860.                 board[61] != bishop && board[62] != knight);
  1861. /* Pawn Storm */
  1862.     if (!PawnStorm && stage < 5)
  1863.     PawnStorm = ((column (wking) < 3 && column (bking) > 4) ||
  1864.              (column (wking) > 4 && column (bking) < 3));
  1865. /* setup base tables */
  1866. #ifndef AMIGA
  1867.     memcpy(Mknight[white],pknight,sizeof(pknight));
  1868.     memcpy(Mknight[black],pknight,sizeof(pknight));
  1869.     memcpy(Mbishop[white],pbishop,sizeof(pbishop));
  1870.     memcpy(Mbishop[black],pbishop,sizeof(pbishop));
  1871. #ifdef notdef
  1872.     CopyBoard (pknight, Mknight[white]);
  1873.     CopyBoard (pknight, Mknight[black]);
  1874.     CopyBoard (pbishop, Mbishop[white]);
  1875.     CopyBoard (pbishop, Mbishop[black]);
  1876. #endif
  1877. #else // use MoveMem128
  1878.  MoveMem128(pknight,Mknight[white]);
  1879.  MoveMem128(pknight,Mknight[black]);
  1880.  MoveMem128(pbishop,Mbishop[white]);
  1881.  MoveMem128(pbishop,Mbishop[black]);
  1882. #endif
  1883. /* linear interpolate on stage    */
  1884. /* Mking = (KingOpening * (10 - stage) + KingEnding * srage) /10  */
  1885.     BlendBoard (KingOpening, KingEnding, Mking[white]);
  1886.     BlendBoard (KingOpening, KingEnding, Mking[black]);
  1887.  
  1888.     for (sq = 0; sq < 64; sq++)
  1889.       {
  1890.       fyle = column (sq);
  1891.       rank = row (sq);
  1892.       wstrong = bstrong = true;
  1893. /* does a black pawn attack to squares in this col from sq to end */
  1894.       for (i = sq; i < 64; i += 8)
  1895.           if (Patak (black, i)) { wstrong = false; break; }
  1896. /* does a white pawn attack to squares in this col from sq to end */
  1897.       for (i = sq; i >= 0; i -= 8)
  1898.           if (Patak (white, i)) { bstrong = false; break; }
  1899. /*     */
  1900.       wpadv = bpadv = PADVNCM;
  1901.       if ((fyle == 0 || PawnCnt[white][fyle - 1] == 0) && (fyle == 7 || PawnCnt[white][fyle + 1] == 0)) wpadv = PADVNCI;
  1902.       if ((fyle == 0 || PawnCnt[black][fyle - 1] == 0) && (fyle == 7 || PawnCnt[black][fyle + 1] == 0)) bpadv = PADVNCI;
  1903.       Mwpawn[sq] = (wpadv * PawnAdvance[sq]) / 10;
  1904.       Mbpawn[sq] = (bpadv * PawnAdvance[63 - sq]) / 10;
  1905.       Mwpawn[sq] += PawnBonus;
  1906.       Mbpawn[sq] += PawnBonus;
  1907. /*     */
  1908.       if (Mvboard[kingP[white]])
  1909.         {
  1910.         if ((fyle < 3 || fyle > 4) && distance (sq, wking) < 3)
  1911.             Mwpawn[sq] += PAWNSHIELD;
  1912.         }
  1913.       else if (rank < 3 && (fyle < 2 || fyle > 5))
  1914.           Mwpawn[sq] += PAWNSHIELD / 2;
  1915. /*     */
  1916.       if (Mvboard[kingP[black]])
  1917.         {
  1918.         if ((fyle < 3 || fyle > 4) && distance (sq, bking) < 3)
  1919.             Mbpawn[sq] += PAWNSHIELD;
  1920.         }
  1921.       else if (rank > 4 && (fyle < 2 || fyle > 5))
  1922.           Mbpawn[sq] += PAWNSHIELD / 2;
  1923. /*     */
  1924.       if (PawnStorm)
  1925.         {
  1926.         if ((column (wking) < 4 && fyle > 4) || (column (wking) > 3 && fyle < 3))
  1927.             Mwpawn[sq] += 3 * rank - 21;
  1928.         if ((column (bking) < 4 && fyle > 4) || (column (bking) > 3 && fyle < 3))
  1929.             Mbpawn[sq] -= 3 * rank;
  1930.         }
  1931. /*     */
  1932.       Mknight[white][sq] += 5 - distance (sq, bking);
  1933.       Mknight[white][sq] += 5 - distance (sq, wking);
  1934.       Mknight[black][sq] += 5 - distance (sq, wking);
  1935.       Mknight[black][sq] += 5 - distance (sq, bking);
  1936. /*     */
  1937.       Mbishop[white][sq] += BishopBonus;
  1938.       Mbishop[black][sq] += BishopBonus;
  1939. /*     */
  1940.       for (i = PieceCnt[black]; i >= 0; i--)
  1941.           if (distance (sq, PieceList[black][i]) < 3)
  1942.           Mknight[white][sq] += KNIGHTPOST;
  1943.       for (i = PieceCnt[white]; i >= 0; i--)
  1944.           if (distance (sq, PieceList[white][i]) < 3)
  1945.           Mknight[black][sq] += KNIGHTPOST;
  1946. /*     */
  1947.       if (wstrong)
  1948.           Mknight[white][sq] += KNIGHTSTRONG;
  1949.       if (bstrong)
  1950.           Mknight[black][sq] += KNIGHTSTRONG;
  1951.       if (wstrong)
  1952.           Mbishop[white][sq] += BISHOPSTRONG;
  1953.       if (bstrong)
  1954.           Mbishop[black][sq] += BISHOPSTRONG;
  1955. /*     */
  1956.  
  1957.       if (HasBishop[white] == 2)
  1958.           Mbishop[white][sq] += 8;
  1959.       if (HasBishop[black] == 2)
  1960.           Mbishop[black][sq] += 8;
  1961.       if (HasKnight[white] == 2)
  1962.           Mknight[white][sq] += 5;
  1963.       if (HasKnight[black] == 2)
  1964.           Mknight[black][sq] += 5;
  1965. /*     */
  1966.  
  1967.       Kfield[white][sq] = Kfield[black][sq] = 0;
  1968.       if (distance (sq, wking) == 1)
  1969.           Kfield[black][sq] = KATAK;
  1970.       if (distance (sq, bking) == 1)
  1971.           Kfield[white][sq] = KATAK;
  1972. /*     */
  1973.       Pd = 0;
  1974.       for (k = 0; k <= PieceCnt[white]; k++)
  1975.         {
  1976.         i = PieceList[white][k];
  1977.         if (board[i] == pawn)
  1978.           {
  1979.               pp = true;
  1980.               z = i + ((row (i) == 6) ? 8 : 16);
  1981.               for (j = i + 8; j < 64; j += 8)
  1982.               if (Patak (black, j) || board[j] == pawn)
  1983.                 {
  1984.                 pp = false;
  1985.                 break;
  1986.                 }
  1987.               Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  1988.           }
  1989.         }
  1990. /*     */
  1991.       for (k = 0; k <= PieceCnt[black]; k++)
  1992.         {
  1993.         i = PieceList[black][k];
  1994.         if (board[i] == pawn)
  1995.           {
  1996.               pp = true;
  1997.               z = i - ((row (i) == 1) ? 8 : 16);
  1998.               for (j = i - 8; j >= 0; j -= 8)
  1999.               if (Patak (white, j) || board[j] == pawn)
  2000.                 {
  2001.                 pp = false;
  2002.                 break;
  2003.                 }
  2004.               Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  2005.           }
  2006.         }
  2007. /*     */
  2008.       if (Pd != 0)
  2009.         {
  2010.         val = (Pd * stage2) / 10;
  2011.         Mking[white][sq] -= val;
  2012.         Mking[black][sq] -= val;
  2013.         }
  2014.       }
  2015. }
  2016.  
  2017.  
  2018. void
  2019. UpdateWeights (void)
  2020.  
  2021. /*
  2022.  * If material balance has changed, determine the values for the positional
  2023.  * evaluation terms.
  2024.  */
  2025.  
  2026. {
  2027.     register short s1;
  2028.  
  2029.     emtl[white] = mtl[white] - pmtl[white] - valueK;
  2030.     emtl[black] = mtl[black] - pmtl[black] - valueK;
  2031.     tmtl = emtl[white] + emtl[black];
  2032.     s1 = ((tmtl > 6600) ? 0 : ((tmtl < 1400) ? 10 : (6600 - tmtl) / 520));
  2033.     if (s1 != stage)
  2034.       {
  2035.       stage = s1;
  2036.       stage2 = ((tmtl > 3600) ? 0 : ((tmtl < 1400) ? 10 : (3600 - tmtl) / 220));
  2037.       PEDRNK2B = -15;    /* centre pawn on 2nd rank & blocked */
  2038.       PBLOK = -4;        /* blocked backward pawn */
  2039.       PDOUBLED = -14;    /* doubled pawn */
  2040.       PWEAKH = -4;        /* weak pawn on half open file */
  2041.       PAWNSHIELD = 10 - stage;    /* pawn near friendly king */
  2042.       PADVNCM = 10;        /* advanced pawn multiplier */
  2043.       PADVNCI = 7;        /* muliplier for isolated pawn */
  2044.       PawnBonus = stage;
  2045.  
  2046.       KNIGHTPOST = (stage + 2) / 3;    /* knight near enemy pieces */
  2047.       KNIGHTSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  2048.  
  2049.       BISHOPSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  2050.       BishopBonus = BBONUS * stage;
  2051.  
  2052.       RHOPN = 10;        /* rook on half open file */
  2053.       RHOPNX = 4;
  2054.       RookBonus = RBONUS * stage;
  2055.  
  2056.       XRAY = 8;        /* Xray attack on piece */
  2057.       PINVAL = 10;        /* Pin */
  2058.  
  2059.       KHOPN = (3 * stage - 30) / 2;    /* king on half open file */
  2060.       KHOPNX = KHOPN / 2;
  2061.       KCASTLD = 10 - stage;
  2062.       KMOVD = -40 / (stage + 1);    /* king moved before castling */
  2063.       KATAK = (10 - stage) / 2;    /* B,R attacks near enemy king */
  2064.       KSFTY = ((stage < 8) ? (KINGSAFETY - 4 * stage) : 0);
  2065.  
  2066.       ATAKD = -6;        /* defender > attacker */
  2067.       HUNGP = -12;        /* each hung piece */
  2068.       HUNGX = -18;        /* extra for >1 hung piece */
  2069.       }
  2070. }
  2071.